import { omit } from "lodash";
import { errLogger, outLogger } from "ROOT/common/logger";
import { MysqlDataSource } from "ROOT/db/orm";
import { SaveOptions } from "typeorm";
import SymbolOrderConfigEntity from "./SymbolOrderConfig.entity";
import StrategyService from 'ROOT/module/strategy/strategy.service';
import WatchEntityService from 'ROOT/module/watch/watch.service';

class SymbolOrderConfigService {
  repository = MysqlDataSource.getRepository(SymbolOrderConfigEntity)
  /**
   * 查询
   * @param {object} query
   */
  async find(query: Partial<Omit<SymbolOrderConfigEntity, 'config'>>, safe?: boolean) {
    const list = await this.repository.find({ relations: ['strategy'], where: query });
    // const tradeAccountMap: Record<number, TradeAccountEntity> = {};

    for (const item of list) {
      if (item.strategy == null) {
        const baseSymbolStrategy = await StrategyService.findOne({ symbol: item.symbol, userid: 0 });
        (item as any).strategy = Object.assign(omit(baseSymbolStrategy, ['userid']), { editable: false });
      }
      // if (tradeAccountMap[item.trade_ccount_id]) {
      //   item.trade_ccount = tradeAccountMap[item.trade_ccount_id];
      // } else {
      //   tradeAccountMap[item.trade_ccount_id] = await TradeAccountService.findOne({ id: item.trade_ccount_id }, safe);
      //   item.trade_ccount = tradeAccountMap[item.trade_ccount_id];
      // }
    }
    return list
  }

  /**
   * 查询单个
   * @param {object} query
   */
  async findOne(query: Partial<SymbolOrderConfigEntity>) {
    const target = await this.repository.findOne({ relations: ['strategy'], where: query });
    if (target && target.strategy == null) {
      const watchEntity = await WatchEntityService.findOne({ symbol: target.symbol });
      if (watchEntity === null) {
        throw Error(`缺失默认模板${target.symbol}`)
      }
      target.strategy = watchEntity.strategy;
      target.strategy_id = watchEntity.strategy_id;
    }
    return target
  }

  /**
   * 更新单个
   * @param {object} query
   * @param { Document }
   */
  async updateOne(query: Partial<SymbolOrderConfigEntity>, newData: Partial<SymbolOrderConfigEntity>, options?: SaveOptions) {
    const target = await this.findOne(query);
    if (!target) {
      throw Error(`${query} 不存在`)
    }
    if (newData.strategy) {
      const strategy = await StrategyService.findOne({ id: newData.strategy.id });
      // 二次查询数据对比是否能更新
      if (strategy) {
        if (strategy.userid === target.userid) {
          await StrategyService.update({ id: target.strategy_id, userid: target.userid }, newData.strategy)
        } else {
          outLogger.warn(`${target.userid} no access change strategy`)
        }
      }
    }
    Object.assign(target, newData);
    return await this.repository.save(target);
  }


  /**
   * 更新多个
   * @param {object} query
   * @param { Document }
   */
  async updateMany(query: Partial<SymbolOrderConfigEntity>, newData: Partial<SymbolOrderConfigEntity>) {
    return this.repository.update(query, newData);
  }

  /**
   * 删除单个
   * @param {object} query
   * @param { Document }
   */
  async deleteOne(query: Partial<SymbolOrderConfigEntity>) {
    const target = await this.findOne(query);
    if (!target) {
      return Promise.reject('remove fail, target not exist');
    }

    if (target.strategy && target.strategy.userid === target.userid) {
      target.strategy = null;
      target.strategy_id = null;
      await this.repository.save(target);
    }
    await this.repository.remove(target);
    // await StrategyService.deleteOne({id: target.strategy_id});
    return target;
  }


  async unbindStrategy(id: number) {
    const list = await this.repository.find({ relations: ['strategy'], where: {} });
    for (const data of list) {
      if (data.strategy && data.strategy.id === id) {
        data.strategy = null;
        data.strategy_id = null;
        await this.repository.save(data);
      }
    }
  }
  /**
   * 新增
   * @param {object} query
   * @param { Document }
   */
  async create(data: Partial<SymbolOrderConfigEntity>) {
    const symbolOrderConfigEntity = new SymbolOrderConfigEntity();
    Object.assign(symbolOrderConfigEntity, data);
    // 关联策略
    const watchEntity = await WatchEntityService.findOne({ symbol: data.symbol });
    if (watchEntity) {
      symbolOrderConfigEntity.strategy = watchEntity.strategy;
      symbolOrderConfigEntity.strategy_id = watchEntity.strategy.id;
    } else {
      throw Error(`${data.symbol} 策略不存在`)
    }
    await this.repository.save(symbolOrderConfigEntity);
    return symbolOrderConfigEntity;
  }

}

export default new SymbolOrderConfigService();

